package com.zyf.swordRefersOffer;

/**
 * 请你来实现一个 stoi 函数,使其能将字符串转换成整数
 * 
 * 首先,该函数会根据需要丢弃无用的开头空格字符,直到寻找到第一个非空格的字符为止.
 * 
 * 当我们寻找到的第一个非空字符串为正或者负号时,则将该符号与之后面尽可能多的连续数字组合起来,作为该整数的正负号;假如第一个非空字符是数字,则直接将其与
 * 之后连续的数字字符组合起来,形成整数
 * 
 * 该字符串除了有效的整数部分之后也可能会存在多余的字符,这些字符可以被忽略,它们对于函数不应该造成影响
 * 
 * 注意 : 假如该字符串中的第一个非空格字符串不是一个有效整数字符,字符串为空或字符串仅包含空白字符时,则你的函数不需要进行转换.
 * 
 * 在任何情况下,若函数不能进行有效的转换时,请返回 0
 * 
 * 假设我们的环境只能存储 32 位大小的有符号整数,那么其数值范围为 [-*2^31 ~ 2^32-1] .如果数值超过这个范围,请返回
 * INT_MAX(2^31 - 1) 或 INT_MIN(-2^31).
 * 
 * 示例 1 : 输入 : "42" 输出 : 42
 * 
 * 示例 2 : 输入 : "-42 " 输出 : -42 解释 : 第一个非空白字符为 '-' ,它是一个负号.
 * 
 * 我们尽可能将负号后面所有连续出现的数字组合起来,最后得到 -42 .
 * 
 * 示例 3 : 输入 : "4193 with words" 输出 : 4193 解释 : 转换截止于数字 '3' ,因为它的下一个字符不为数字
 * 
 * 示例 4 : 输入 : "words and 987" 输出 : 0 解释 : 第一个非空字符是 'w' ,但它不是数字或正负号.因此无法执行有效的转换.
 * 
 * 示例 5 : 输入 : "-9128347232" 输出 : -2147483648 解释 : 数字 "-9128347232"
 * 超过32位有符号整数范围.因此返回 INT_MIN(-2^31)
 * 
 * @author lenovo
 * @Date 2020年7月13日
 * @Time 下午10:44:13
 */
public class _04_Solution {

	public static void main(String[] args) {
		String s1 = "42";
		String s2 = "-42";
		String s3 = "4193 with words";
		String s4 = "words and 987";
		String s5 = "-9128347232";
		System.out.println(myAtoi(s1));
		System.out.println(myAtoi(s2));
		System.out.println(myAtoi(s3));
		System.out.println(myAtoi(s4));
		System.out.println(myAtoi(s5));
	}

	// Ctrl + shift + F 可以一键格式化代码,规范风格
	public static int myAtoi(String str) {
		str = str.trim();
		int len = str.length();
		if (len == 0 || str == null) {
			return 0;
		}
		int i = 0;
		long result = 0;
		boolean flag = true;
		if (str.charAt(i) == '+') {
			i++;
		} else if (str.charAt(i) == '-') {
			i++;
			flag = false;
		} else if ('0' > str.charAt(i) || str.charAt(i) > 'a') {
			return 0;
		}
		int count = 0;
		for (; i < len; i++) {
			char a = str.charAt(i);
			if ('0' <= a && a <= '9') {
				result = result * 10 + (a - '0');
				if (result != 0) {
					count++;
				}
				if (count > 10) {
					return flag ? Integer.MAX_VALUE : Integer.MIN_VALUE;
				}
			} else {
				break;
			}
		}
		result = flag ? result : -result;
		if (result > (long) Integer.MAX_VALUE || result < (long) Integer.MIN_VALUE) {
			return flag ? Integer.MAX_VALUE : Integer.MIN_VALUE;
		}
		return (int) result;
	}
}
